home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / smaltalk.lha / smalltalk-1.1.1 / SequenceableCollection.st < prev    next >
Text File  |  1991-09-12  |  9KB  |  298 lines

  1. "======================================================================
  2. |
  3. |   SequenceableCollection Method Definitions
  4. |
  5.  ======================================================================"
  6.  
  7.  
  8. "======================================================================
  9. |
  10. | Copyright (C) 1990, 1991 Free Software Foundation, Inc.
  11. | Written by Steve Byrne.
  12. |
  13. | This file is part of GNU Smalltalk.
  14. |
  15. | GNU Smalltalk is free software; you can redistribute it and/or modify it
  16. | under the terms of the GNU General Public License as published by the Free
  17. | Software Foundation; either version 1, or (at your option) any later version.
  18. | GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
  19. | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  20. | FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
  21. | details.
  22. | You should have received a copy of the GNU General Public License along with
  23. | GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
  24. | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  
  25. |
  26.  ======================================================================"
  27.  
  28.  
  29. "
  30. |     Change Log
  31. | ============================================================================
  32. | Author       Date       Change 
  33. | sbb         12 Sep 91      Fixed indexOfSubCollection.
  34. |
  35. | sbyrne     19 Sep 89      Converted to use real method categories.
  36. |
  37. | sbyrne     25 Apr 89      created.
  38. |
  39. "
  40.  
  41. Collection variableSubclass: #SequenceableCollection
  42.        instanceVariableNames: ''
  43.        classVariableNames: ''
  44.        poolDictionaries: ''
  45.        category: nil.
  46.  
  47. SequenceableCollection comment: 
  48. 'My instances represent collections of objects that are ordered.  I provide
  49. some access and manipulation methods.' !
  50.  
  51.  
  52. !SequenceableCollection methodsFor: 'basic'!
  53.  
  54. atAll: aCollection put: anObject
  55.     aCollection do: [ :index | self at: index put: anObject ]
  56. !
  57.  
  58. atAllPut: anObject
  59.     1 to: self size do: [ :index | self at: index put: anObject ]
  60. !
  61.  
  62. first
  63.     ^self at: 1
  64. !
  65.  
  66. last
  67.     self size < 1 ifTrue: [ ^self error: 'last not defined with no elements' ].
  68.     ^self at: self size
  69. !
  70.  
  71. indexOf: anElement ifAbsent: exceptionBlock
  72.     1 to: self size do: [ :index | (self at: index) = anElement
  73.                                      ifTrue: [ ^index ] ].
  74.     ^exceptionBlock value
  75. !
  76.  
  77. indexOf: anElement
  78.     ^self indexOf: anElement ifAbsent: [ ^0 ]
  79. !!
  80.  
  81.  
  82.  
  83. !SequenceableCollection methodsFor: 'nonpublic methods'!
  84.  
  85. matchSubCollection: aSubCollection startingAt: anIndex
  86.     2 to: aSubCollection size do:
  87.         [ :index | (self at: anIndex + index - 1) ~= (aSubCollection at: index)
  88.                    ifTrue: [ ^false ]
  89.     ].
  90.     ^true
  91. !
  92.  
  93. indexOfSubCollection: aSubCollection startingAt: anIndex
  94.     ifAbsent: exceptionBlock
  95.     | selfSize subSize |
  96.     subSize  _ aSubCollection size.
  97.     selfSize _ self size.
  98.     anIndex + subSize - 1 <= selfSize ifTrue:
  99.     [ anIndex to: selfSize - subSize + 1 do:
  100.           [:index | (self at: index) = (aSubCollection at: 1)
  101.                 ifTrue: [(self matchSubCollection: aSubCollection
  102.                        startingAt: index)
  103.                      ifTrue: [^index]
  104.                      ]
  105.                 ]
  106.           ].
  107.     ^exceptionBlock value
  108. !
  109.  
  110. indexOfSubCollection: aSubCollection startingAt: anIndex
  111.     ^self indexOfSubCollection: aSubCollection startingAt: anIndex
  112.         ifAbsent: [ ^0 ]
  113. !
  114.  
  115. replaceFrom: start to: stop with: replacementCollection startingAt: repStart
  116.     (self == replacementCollection and: [ repStart ~= 1 ])
  117.         ifTrue: [ ^self error: 'replaceFrom:to:with:startingAt: called for 
  118. in-place replacement, but starting index was not 1' ].
  119.     1 to: stop - start + 1 do:
  120.         [ :index |
  121.       self at: (start + index - 1)
  122.                put: (replacementCollection at: (repStart + index - 1)) ]
  123. !
  124.  
  125. replaceFrom: start to: stop with: replacementCollection
  126.     stop - start + 1 ~= replacementCollection size
  127.         ifTrue: [ ^self error: 'replacement range does not equal size of
  128. replacement collection' ].
  129.     self replaceFrom: start to: stop with: replacementCollection startingAt: 1
  130. !!
  131.  
  132.  
  133.  
  134. !SequenceableCollection methodsFor: 'copying SequenceableCollections'!
  135.  
  136. , aSequenceableCollection
  137.     | newCollection |
  138.     newCollection _ self species new: (self size + aSequenceableCollection size).
  139.     newCollection replaceFrom: 1 to: self size with: self.
  140.     newCollection replaceFrom: (self size) + 1
  141.                   to: self size + aSequenceableCollection size
  142.           with: aSequenceableCollection.
  143.     ^newCollection
  144. !
  145.  
  146. copyFrom: start to: stop
  147.     | newCollection len |
  148.     len _ stop - start + 1.
  149.     newCollection _ self species new: len.
  150.     newCollection replaceFrom: 1 to: len with: self startingAt: start.
  151.     ^newCollection
  152. !
  153.  
  154. copyReplaceAll: oldSubCollection with: newSubCollection
  155.     | numOld newCollection sizeDifference newSubSize oldSubSize
  156.       newStart oldStart copySize index |
  157.     numOld _ self countSubCollectionOccurrencesOf: oldSubCollection.
  158.     newSubSize _ newSubCollection size.
  159.     sizeDifference _ newSubSize - oldSubCollection size + 1.
  160.     newCollection _ self species new: (self size - (sizeDifference * numOld)).
  161.     oldStart _ newStart _ 1.
  162.     [ index _ self indexOfSubCollection: oldSubCollection
  163.                    startingAt: oldStart.
  164.       index > 0 ] whileTrue:
  165.         [ copySize _ index - oldStart + 1.
  166.       newCollection replaceFrom: newStart
  167.                     to: newStart + copySize - 1
  168.             with: self
  169.             startingAt: oldStart.
  170.       newStart _ newStart + copySize - 1.
  171.       newCollection replaceFrom: newStart
  172.                     to: newStart + newSubSize - 1
  173.             with newSubCollection.
  174.           oldStart _ oldStart + copySize.
  175.           newStart _ newStart + newSubSize ].
  176.     "Copy the remaining part of self onto the tail of the new collection."
  177.     newCollection replaceFrom: newStart
  178.                  to: newCollection size
  179.          with: self
  180.          startingAt: oldStart.
  181.     ^newCollection
  182. !
  183.  
  184. copyReplaceFrom: start to: stop with: replacementCollection
  185.     | newCollection newSize repSize |
  186.     "### check for bounds "
  187.     repSize _ replacementCollection size.
  188.     newSize _ self size + repSize - (stop - start + 1).
  189.     newCollection _ self species new: newSize.
  190.     newCollection replaceFrom: 1 to: start - 1 with: self startingAt: 1.
  191.     newCollection replaceFrom: start
  192.                   to: start + repSize - 1
  193.           with: replacementCollection.
  194.     newCollection replaceFrom: start + repSize
  195.                   to: newCollection size
  196.           with: self
  197.           startingAt: stop + 1.
  198.     ^newCollection
  199. !
  200.  
  201. copyWith: newElement
  202.     | newCollection len |
  203.     len _ self size + 1.
  204.     newCollection _ self species new: len.
  205.     newCollection replaceFrom: 1 to: self size with: self.
  206.     newCollection at: len put: newElement.
  207.     ^newCollection
  208. !
  209.  
  210. copyWithout: oldElement
  211.     | newCollection numOccurrences i |
  212.     numOccurrences _ 0.
  213.     self do:
  214.         [ :element |
  215.       element = oldElement
  216.         ifTrue: [ numOccurrences _ numOccurrences + 1 ] ].
  217.     newCollection _ self species new: (self size - numOccurrences).
  218.     i _ 1.
  219.     self do:
  220.         [ :element |
  221.       element ~= oldElement
  222.         ifTrue: [ newCollection at: i put: element.
  223.                   i _ i + 1 ]
  224.     ].
  225.     ^newCollection
  226. !!
  227.  
  228.  
  229.  
  230. !SequenceableCollection methodsFor: 'enumerating'!
  231.  
  232. do: aBlock
  233.     "Evaluate aBlock for all elements in the sequenceable collection"
  234.     1 to: self size do:
  235.         [ :i | aBlock value: (self at: i) ]
  236. !
  237.  
  238. findFirst: aBlock
  239.     "Returns the index of the first element of the sequenceable collection
  240.     for which aBlock returns true"
  241.     1 to: self size do:
  242.         [ :i | (aBlock value: (self at: i))
  243.              ifTrue: [ ^i ] ].
  244.     ^0
  245. !
  246.  
  247. findLast: aBlock
  248.     self size to: 1 by: -1 do:
  249.         [ :i | (aBlock value: (self at: i))
  250.              ifTrue: [ ^i ] ].
  251.     ^0
  252. !
  253.  
  254. reverseDo: aBlock
  255.     self size to: 1 by: -1 do:
  256.         [ :i | aBlock value: (self at: i) ]
  257. !
  258.  
  259. with: aSequenceableCollection do: aBlock
  260.     self size = aSequenceableCollection size
  261.         ifFalse:
  262.         [ ^self error: 'sequenceable collections must have same size' ].
  263.     1 to: self size do:
  264.         [ :i | aBlock value: (self at: i)
  265.                   value: (aSequenceableCollection at: i) ]
  266. !!
  267.  
  268.  
  269.  
  270. !SequenceableCollection methodsFor: 'private methods'!
  271.  
  272. countSubCollectionOccurrencesOf: aSubCollection
  273.     | colIndex subColIndex count |
  274.     colIndex _ 1.
  275.     count _ 0.
  276.     [ subColIndex _ self indexOfSubCollection: aSubCollection
  277.                          startingAt: colIndex.
  278.       subColIndex > 0 ] whileTrue:
  279.           [ count _ count + 1.
  280.       colIndex _ colIndex + aSubCollection size ].
  281.     ^count
  282. !
  283.  
  284. grow
  285.     | newCollection |
  286.     newCollection _ self species new: self basicSize + self growSize.
  287.     newCollection replaceFrom: 1 to: self size with: self.
  288.     ^self become: newCollection
  289. !
  290.     
  291. growSize
  292.     ^10                "a randomly chosed number"
  293.  
  294. !!
  295.  
  296.